<html>
<head><meta charset="utf-8"><title>Support for callsite attributes · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html">Support for callsite attributes</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="223054928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223054928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hugues de Valon <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223054928">(Jan 17 2021 at 17:57)</a>:</h4>
<h1>Intro</h1>
<p>LLVM has support for <a href="https://llvm.org/docs/LangRef.html#call-site-attributes">callsite attributes</a>, attributes that modify the code generation of function calls. There are associated functions to activate them in the Rust code base under the names <code>LLVMRustAddCallSiteAttr*</code>. As far as I know, they are only used internally by the compiler for some specific attributes (I might be wrong!).<br>
More generally, I don't think there are today any attribute that can be used in Rust code on function calls to trigger LLVM call site attributes. Things like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">toto</span><span class="p">(</span><span class="n">arg</span>: <span class="kt">u32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">u32</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">..</span><span class="p">.</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">tata</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="cp">#[callsite_attribute]</span><span class="w"> </span><span class="n">toto</span><span class="p">)(</span><span class="mi">56</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>And to be fair, I don't know if there are any call site attributes that would be useful today in Rust (so that's probably why it's not supported).</p>
<h1>Some context</h1>
<p>The reason why I am interested in callsite attribute is to add support to one in particular, <code>cmse_nonsecure_call</code>.<br>
This attribute is specific to the Armv8-M architecture profiles (<code>thumbv8m*</code> targets) to support part of the TrustZone-M extension. Very shortly, this extension defines Secure and Non-Secure worlds and this attribute marks a call to a Non-Secure function from the Secure code so that code generation is modified to have the registers cleared (to not leak possible confidential data) and some other things. If you are interested, <a href="https://developer.arm.com/documentation/ecm0359818/latest">here</a> are the specs and <a href="https://reviews.llvm.org/D71129">here</a> is the commit implementing it in LLVM.</p>
<p>Now, the finality of supporting this attribute in Rust is a LLVM call to <code>LLVMRustAddCallSiteAttr</code> to add the <code>cmse_nonsecure_call</code> attribute to the callsite.<br>
I have been prototyping and made it work by checking in the HIR, when building the MIR terminator Call node, if the attribute is set and decorate the MIR Call structure with the information of the presence of that attribute or not (as a <code>bool</code>). At code generation, if the field is set to <code>true</code>, then the LLVM function will be called. This caters for the previously described syntax, where the attribute is directly set on the function name with parenthesis (other syntaxes do not seem to work, the attribute is lost).</p>
<p>In C, this is done through a typedef to declare a new function pointer <em>type</em> which will apply the attribute everytime the pointed function is called:</p>
<div class="codehilite" data-code-language="C"><pre><span></span><code><span class="k">typedef</span> <span class="kt">void</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">cmse_nonsecure_call</span><span class="p">))</span> <span class="n">nsfunc</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
</code></pre></div>
<p>I was not sure on how to transpose that in Rust, and just doing <code>(#[cmse_nonsecure_call] toto)()</code> was also easier to implement :D</p>
<p>It was also proposed for this attribute to be implemented through a new ABI. I am open to any option at this point as long as we do not deviate too much from the spec (but which was written with C in mind only).</p>
<h1>About callsite attribute in general</h1>
<p>If using a callsite attribute is the chosen path to implement <code>cmse_nonsecure_call</code> then it might make sense to add this as a feature? As in instead of just checking if the <code>cmse_nonsecure_call</code> attribute is there, check for a subset of attributes that are allowed and encode them in a field in the MIR Call node. This can be similar (or actually equal) to the <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/middle/codegen_fn_attrs/struct.CodegenFnAttrFlags.html">CodegenFnAttrFlags</a> for example. Then at code generation check for all attributes set in the bitflags and apply them.</p>



<a name="223056553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056553">(Jan 17 2021 at 18:38)</a>:</h4>
<p>Hmm, if even C makes this part of the function's type, why shouldn't Rust?</p>



<a name="223056645"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056645" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056645">(Jan 17 2021 at 18:41)</a>:</h4>
<p>I imagine you'd use either a different abi or give a symbol different path through extern {}.</p>



<a name="223056655"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056655" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056655">(Jan 17 2021 at 18:41)</a>:</h4>
<p>Either way probably needs an rfc</p>



<a name="223056722"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056722" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056722">(Jan 17 2021 at 18:42)</a>:</h4>
<p>(actually I think adding an abi wouldn't be too contraversial)</p>



<a name="223056733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056733">(Jan 17 2021 at 18:43)</a>:</h4>
<p>Adding an ABI for this is what I suggested in the past as well</p>



<a name="223056740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056740">(Jan 17 2021 at 18:43)</a>:</h4>
<p>Would be happy to review a PR that does that</p>



<a name="223056797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223056797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223056797">(Jan 17 2021 at 18:44)</a>:</h4>
<p>But I'd also be interested in knowing why a call-site attribute would be superior. Is there any situation in which users sometimes want to do a non-secure call to a function only some of the time?</p>



<a name="223088812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223088812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nihal Pasham <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223088812">(Jan 18 2021 at 07:42)</a>:</h4>
<p><code>Is there any situation in which users sometimes want to do a non-secure call to a function only some of the time?</code> - for the most part there are  2  kinds of <code>secure-to-non secure</code> calls  </p>
<ul>
<li>The very first call that's needed after bootup and TrustZone hardware initialization, when we want to pass execution-control to the non-secure firmware and</li>
<li>When the secure world wants to explicitly call into the non-secure world. For ex: Secure world could be running something like a <code>system integrity checker</code> that passively monitors  the non-secure world  with periodic calls.</li>
</ul>



<a name="223107899"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223107899" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hugues de Valon <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223107899">(Jan 18 2021 at 11:21)</a>:</h4>
<blockquote>
<p>if even C makes this part of the function's type, why shouldn't Rust?</p>
</blockquote>
<p>Yes agree that ideally it would be easier and safer (so that the secure code writers do not forget it) to have the attribute on the function's type.</p>
<blockquote>
<p>But I'd also be interested in knowing why a call-site attribute would be superior. Is there any situation in which users sometimes want to do a non-secure call to a function only some of the time?</p>
</blockquote>
<p>For the user I am not sure that it would be superior. I started doing it that way in my prototype because I was simply copying C and creating a new call site attribute.<br>
Agree with <span class="user-mention" data-user-id="360867">@Nihal Pasham</span> here about the two cases. I can add that the second one can be generalised to any kind of callback the Non-Secure side wants to register to the Secure side (for example for a periodic interrupt). When it's time for the Secure side to call the callback, it will have to do it with this attribute.<br>
On those two cases, the Secure side only has an address of a Non-Secure function it wants to call (because it does not link to the Non-Secure code) and so it has to <em>cast</em> this address to a function pointer type to call it. In the first case, this address is the one of the Non-Secure reset handler and in the second case this address can be anything in the Non-Secure address space.</p>
<p>If we go the ABI route, is it possible to specify an ABI on a function pointer and then to cast an address to that?</p>
<p>Looking at <a href="https://doc.rust-lang.org/reference/items/functions.html#extern-function-qualifier">this</a> it looks like it might be possible to do something like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">non_secure_function</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="n">transmute</span>::<span class="o">&lt;</span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="k">extern</span><span class="w"> </span><span class="s">"cmse_nonsecure_call"</span><span class="w"> </span><span class="k">fn</span><span class="p">(</span><span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span><span class="o">&gt;</span><span class="p">(</span><span class="mh">0x10000004</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>(I am not sure of the cast syntax at all from the top of my head).</p>
<p>Then it would be nice because every call to <code>non_secure_function</code> would set the callsite attribute in LLVM.</p>
<p>Also, similarly to what we discussed on the other <a href="https://github.com/rust-lang/rust/pull/75810#discussion_r475220877">PR</a>, we will need to restrict to a C ABI and only passing arguments by registers (this is checked by LLVM as well).</p>
<p>To summarize, the new <code>cmse_nonsecure_call</code> ABI would:</p>
<ul>
<li>be a C ABI</li>
<li>setting a callsite <code>cmse_nonsecure_call</code> attribute on every call</li>
<li>restrict the number of parameters/return value to only use registers (that can probably be a follow-up task to be done in Rust side as this is currently checked in LLVM)</li>
</ul>



<a name="223117615"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223117615" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223117615">(Jan 18 2021 at 13:11)</a>:</h4>
<p>Sounds reasonable!</p>



<a name="223824758"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223824758" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hugues de Valon <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223824758">(Jan 24 2021 at 17:26)</a>:</h4>
<p>FYI, the PR is here: <a href="https://github.com/rust-lang/rust/pull/81346">https://github.com/rust-lang/rust/pull/81346</a><br>
I assumed it was OK not to go through a RFC but can change :)</p>



<a name="223825772"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Support%20for%20callsite%20attributes/near/223825772" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes.html#223825772">(Jan 24 2021 at 17:48)</a>:</h4>
<p>Woo, nice!</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>